#include <signal.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>	/* sleep */


jmp_buf env;
//信号处理函数
void recvSignal(int sig)
{
	printf("received signal %d !!!\n",sig);
			longjmp(env,1);
}
int main(int argc,char** argv)
{

    for(int i = 0; i < 2; i++)
    {
            //保存一下上下文
        int r = setjmp(env);
        if(  r  == 0)
        {
            //初次执行 ，那么可以执行 可能会发生错误的代码
            //给信号注册一个处理函数
            signal(SIGSEGV, recvSignal);
            printf("excute this code!!\n");
               int* s = 0;
                (*s) = 1;
        }
        else
        {
                //是由longjmp 跳转回来的
                printf("jump this code!!\n");
        }
        sleep(5);
    }

    while(1)
    {
        sleep(1);
        printf("sleep 1 \n");
    }

    return 0;
}

#if 0

当for循环第二次执行的时候 ，程序依然产生了 SIGSEGV，系统仍然调用了默认的处理函数产生了core文件 ，
分析下原因"进入到信号处理函数之后 这个信号会被阻塞（block） 直到信号处理函数返回"，在进入到信号处理函数之后，
这个时候系统阻塞了 SIGSEGV 这个信号 ，当跳回到 int r = setjmp(env); 这行代码的时候  SIGSEGV 信号依然是阻塞的，
那以后再给他绑定信号处理函数自然没有作用。

好在系统提供了int sigsetjmp(sigjmp_buf env, int savesigs); 和 void siglongjmp(sigjmp_buf env, int val);这两个函数 ，
这两个函数和上面的 int setjmp(jmp_buf env);   void longjmp(jmp_buf env, int val); 大同小异 ，
唯一的不同 是sigsetjmp 函数 多了一个参数 savesigs，当 savesigs 不为 0时会保存当前的信号屏蔽表 (signal mask)，
然后在使用siglongjmp 跳转的时候会恢复线程的屏蔽表。

#endif